package com.translate.web.service.impl;

import com.translate.entity.Order;
import com.translate.web.constant.RedisConstant;
import com.translate.web.dao.OrderMapper;
import com.translate.web.dao.PayManagerMapper;
import com.translate.web.param.contract.IIdAndUserIdParam;
import com.translate.web.param.contract.IManuscriptAddParam;
import com.translate.web.param.contract.IPayBehaviorRequestParam;
import com.translate.web.param.contract.IPayManagerAddParam;
import com.translate.web.param.contract.IPayManagerSearchParam;
import com.translate.web.param.contract.IPayManagerServiceAddParam;
import com.translate.web.param.contract.IUserIdParam;
import com.translate.entity.PayManager;
import com.translate.vo.contract.IOrderInfoVO;
import com.translate.web.service.IPayManagerService;
import com.basic.service.impl.BaseServiceImpl;
import com.common.util.SnowFlake;
import com.dao.base.IBaseMapper;
import com.page.PageResponseData;
import com.param.contract.IPage;

import java.math.BigDecimal;
import java.sql.Connection;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
public class PayManagerServiceImpl extends BaseTranslateServiceImpl<PayManager> implements IPayManagerService {
	public PayManagerServiceImpl(PayManagerMapper mapper) {
		super(mapper);
	}

	protected void insertPropteris(PayManager data) {
		long time = System.currentTimeMillis() / 1000;
		data.setCreateTime(time);
		data.setUpdateTime(time);
	}

	protected void updatePropteris(PayManager data) {
		data.setUpdateTime(System.currentTimeMillis() / 1000);
	}

	protected Class<PayManager> getEntityClass() {
		return PayManager.class;
	}
	
	protected <S extends IPage> String sqlByGetCounttAfterProcesser(S param) {
		
		IPayManagerSearchParam userIdParam = (IPayManagerSearchParam) param;
		
		List<Integer> userIds = userIdParam.getUserIds();
		
		int teamId = userIdParam.getTeamId();
		
		if (-1 != teamId) {
			// 团队搜索
			return this.sqlByGetCount(" order_status in(0,1,2) and team_id = " + teamId);
		}
		
		
		if (null == userIds || 0 == userIds.size()) {
			return this.sqlByGetCount("");
		}
		
		return this.sqlByGetCount(" order_status in(0,1,2) and user_id = " + userIds.get(0));
	}
	
	protected <S extends IPage> int count(Connection connection, S pageParam) {
		
		int count = super.count(connection, pageParam);
		
		if (0 < count) {
			
			IPayManagerSearchParam userIdParam = (IPayManagerSearchParam) pageParam;
			
			userIdParam.setUserFound(1);
		}
		
		return count;
	}
	
	
	protected <S extends IPage> String sqlByGetPageListAfterProcesser(S param) {
		
		IPayManagerSearchParam userIdParam = (IPayManagerSearchParam) param;
		
		int teamId = userIdParam.getTeamId();
		
		if (-1 != teamId) {
			// 团队搜索
			return this.sqlByGetPageList(" and  order_status in(0,1,2) and team_id = " + teamId+ " order by create_time desc");
		}
		
		List<Integer> userIds = userIdParam.getUserIds();
		
		if (null == userIds || 0 == userIds.size()) {
			return this.sqlByGetPageList("");
		}
		
		// 个人 数据
		return this.sqlByGetPageList(" and order_status in(0,1,2) and user_id = " + userIds.get(0) +" order by create_time desc");
	}

	
	
	
	
	@Override
	public <S extends IPage, VO> PageResponseData<VO> getDataByListBySearch(S marketSearchParam,
			Class<VO> targetClass) {
		// TODO Auto-generated method stub
		PageResponseData<VO> dataByListBySearch = super.getDataByListBySearch(marketSearchParam, targetClass);
		
		if (0 == dataByListBySearch.getTotal()) {
			return dataByListBySearch;
		}
		
		IPayManagerSearchParam param = (IPayManagerSearchParam) marketSearchParam;
		
		param.setUserFound(1);
		
		
		return dataByListBySearch;
	}

	@Override
	@Transactional(propagation = Propagation.MANDATORY)
	public int cancelOrder(int managerId, int userId) {
		
		PayManagerMapper managerMapper = this.getBaseMapper();
		
		return managerMapper.cancelOrder(managerId, userId);
	}

	@Override
	public int cancelTicket(int userId) {
		PayManagerMapper managerMapper = this.getBaseMapper();
		return managerMapper.cancelTicket( userId);
	}

	@Override
	public PayManager getPayManager(IPayBehaviorRequestParam payBehaviorRequestParam) {
		
		PayManagerMapper managerMapper = this.getBaseMapper();
		
		return managerMapper.getPayManagerByP(payBehaviorRequestParam);
	}
	
	
	

	@Override
	public PayManager getPayManagerByTeam(IPayBehaviorRequestParam payBehaviorRequestParam) {
		PayManagerMapper managerMapper = this.getBaseMapper();
		return managerMapper.getPayManagerByTeam(payBehaviorRequestParam);
	}
	

	@Override
	@Transactional(propagation = Propagation.MANDATORY)
	public int paySuccess(IPayBehaviorRequestParam behaviorRequestParam) {
		PayManagerMapper managerMapper = this.getBaseMapper();
		
		return managerMapper.paySuccess(behaviorRequestParam);
		
	}

	@Override
	@Transactional(propagation = Propagation.MANDATORY)
	public int toBeConfirmed(IPayBehaviorRequestParam behaviorRequestParam) {
		PayManagerMapper managerMapper = this.getBaseMapper();
		
        return managerMapper.toBeConfirmed(behaviorRequestParam);
	}
	
	@Transactional(propagation = Propagation.MANDATORY)
	@Override
	public int updateMoney(int paymanagerId, BigDecimal amount, String typeName,  boolean iscancel) {
		
		PayManagerMapper managerMapper = this.getBaseMapper();
		
		PayManager selectByPrimaryKey = managerMapper.selectMoney(paymanagerId);
		
		if (null == selectByPrimaryKey) {
            throw new IllegalArgumentException("找不到支付管理");
        }
		
		
		String serviceNames = selectByPrimaryKey.getServiceNames();
		
		String[] split = serviceNames.split("\\+");
		
		StringBuilder res = new StringBuilder();
		
		for (int i = 0; i < split.length; i++) {
			if (typeName.equals(split[i])) {
				continue;
			}
			
			res = res.append(split[i]).append("+");
		}
		
		int length = res.length();
		
		if (length == 0) {
			typeName = "";
		} else {
			typeName = res.substring(0, length -1);
		}
		
		
		PayManager manager = new PayManager();
		
		manager.setId(paymanagerId);
		
		manager.setServiceNames(typeName);
		
		if (true == iscancel) {
			manager.setOrderStatus( (byte) -1);
		}
		
		manager.setPriceSum(selectByPrimaryKey.getPriceSum().subtract(amount));
		
		return this.mapper.updateByPrimaryKeySelective(manager);
	}

	@Override
	@Transactional(propagation = Propagation.MANDATORY)
	public int drawAndPayImmediately(
			IPayBehaviorRequestParam behaviorRequestParam, BigDecimal money,
			int teamId, String orderSn,
			String serviceType
	) {
		
		PayManagerMapper managerMapper = this.getBaseMapper();
		
		PayManager payManager = new PayManager();
		
		payManager.setUserId((int) behaviorRequestParam.getUserId());
		
		payManager.setPriceSum(money);
		
		payManager.setPayType(behaviorRequestParam.getPayType());
		
		int pos = orderSn.indexOf("-");
		if (-1 != pos) {
			orderSn = orderSn.substring(0, pos);
		}
		
		payManager.setOrderSnId(orderSn);
		
		payManager.setOrderStatus((byte) 0);
		
		payManager.setTranslate((byte) 0);
		
		payManager.setTeamId(teamId);
		
		payManager.setServiceNames(serviceType);;
		
		insertPropteris(payManager);
		
		managerMapper.insert(payManager);
		
		return payManager.getId();
	}

	@Resource
	public void setRedisTemplate(RedisTemplate<String, ? extends Object> redisTemplate) {
		this.redisTemplate = redisTemplate;
	}
	
	
	private interface IRecivePayManagerData {
		
		PayManager apply(IIdAndUserIdParam param, int teamId);
	};
	
	IRecivePayManagerData[] functions = new IRecivePayManagerData[] {
			(IIdAndUserIdParam param, int teamId) -> {
				String payOrderInfoKey = RedisConstant.getPayOrderInfoKey(param.getId(), param.getUserId());
				
				return this.getDataDetailFromCache(param, payOrderInfoKey, 6);
			},
			
			(IIdAndUserIdParam param, int teamId) -> {
				PayManagerMapper mapper = this.getBaseMapper();
				
				return mapper.getDataByIdAndTeamId(param.getId(), teamId);
			},
	};
	
	
	@Override
	public <VO extends IOrderInfoVO> VO getOrderInfo(IIdAndUserIdParam param , Class<VO> type, Byte isRegimental, int teamId) {
		
		
		PayManager dataDetailFromCache = functions[isRegimental].apply(param, teamId);
		
		if (null == dataDetailFromCache) {
			return null;
		}
		
		if (2 != dataDetailFromCache.getOrderStatus().intValue()) {
			throw new RuntimeException("订单未支付，请支付后在申请开票");
		}
		
		try {
			VO orderInfo = type.newInstance();
			
			orderInfo.setId(dataDetailFromCache.getId());
			
			orderInfo.setOrderSnId(dataDetailFromCache.getOrderSnId());
			
			orderInfo.setServiceId(1);
			
			orderInfo.setMoney(dataDetailFromCache.getPriceSum());
			
			return orderInfo;
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public int updateTraslate(int assocId) {
		
		PayManagerMapper managerMapper = this.getBaseMapper();
		
		PayManager payManager = new PayManager();
		
		payManager.setId(assocId);
		
		payManager.setTranslate((byte) 1);
		
		return managerMapper.updateByPrimaryKeySelective(payManager);
	}

	@Override
	public int cancelOrderByTeam(int managerId, int teamId) {
		
		PayManagerMapper managerMapper = this.getBaseMapper();
		
		return managerMapper.cancelOrderByTeam(managerId, teamId);
	}
	@Override
	public List<Order> getOrdersByPayManagerIdAndPayType(int payManagerId, int userId) {
		PayManagerMapper managerMapper = this.getBaseMapper();
		return managerMapper.getOrdersByPayManagerIdAndPayType(payManagerId, userId);
	}
	@Override
	public int paySuccessByTeam(IPayBehaviorRequestParam behaviorRequestParam) {
		PayManagerMapper managerMapper = this.getBaseMapper();
		return managerMapper.paySuccessByTeam(behaviorRequestParam);
	}
	
	@Override
	public int toBeConfirmedByTeam(IPayBehaviorRequestParam behaviorRequestParam) {
		PayManagerMapper managerMapper = this.getBaseMapper();
		return managerMapper.toBeConfirmedByTeam(behaviorRequestParam);
	}

	@Override
	public PayManager getPayManager(int managerId, int teamId) {
		
		PayManagerMapper managerMapper = this.getBaseMapper();
		
		return managerMapper.getDataByIdAndTeamId(managerId, teamId);
	}

	@Override
	public BigDecimal sumPriceByTeam(int teamId) {
		PayManagerMapper managerMapper = this.getBaseMapper();
		BigDecimal sumPriceByTeam = managerMapper.sumPriceByTeam(teamId);
		
		if (null == sumPriceByTeam) {
            sumPriceByTeam = BigDecimal.ZERO;
        }
		
		return sumPriceByTeam;
	}

	@Override
	public BigDecimal sumPriceByRechargePay(int teamId) {
		
		PayManagerMapper managerMapper = this.getBaseMapper();

		
		BigDecimal sumPriceByRechargePay = managerMapper.sumPriceByRechargePay(teamId);
		
		if (null == sumPriceByRechargePay) {
            sumPriceByRechargePay = BigDecimal.ZERO;
        }
		
		return sumPriceByRechargePay;
	}

}